<?php
/**
* lucene索引模型
* @author       Steven.liao
*/
class Lucene implements iLucene
{
    /**
    * 索引配置文件数据
    * @var      object
    */
    protected $_ini;
    
    /**
    * 索引名称
    * @var      string
    */
    protected $_name;
    
    /**
    * 返回数据条数
    * @var      int
    */
    protected $_limit = 50;
    
    /**
    * 执行时间
    * @var      int
    */
    protected $_time;
    
    /**
    * 当前页
    * @var      int
    */
    protected $_page = 1;
    
    /**
     * 查询的关键字
     */
    protected $_keyword;
    
    /**
     * Document 列表
     */
    protected $_docs = array();
    
    /**
     * 是否启用缓存
     */
    protected $_cache = true;
    
    protected $_url = "http://192.168.10.254:8080/Service/SE";
	/**
    * 初始化
    * 读到配置文件,
    * 设定索引编码
    * @return   void
    */
	public function __construct()
	{
		$this->_logger = Logger::factory('Lucene','db');
	}
	/**
	 * 设定主机URL;
	 * @param string $url
	 * @return Object this
	 */
	public function setURL($url){
		$this->_url = $url;
		return $this;
	}
	/**
	 * 取得主机URL;
	 * @return String
	 */
	public function getURL(){
		return $this->_url;
	}
    /**
    * 返回索引对象
    * @param    string $name    索引名，对应index.ini文件
    * @return   object
    */
	public function setName($name)
	{
		$this->_name = $name;
		return $this;
	}
	
    /**
    * 取得索引名
    * @return   string
    */
	public function getName()
	{
		return $this->_name;	
	}
	
	/**
    * 设定查询的关键字
    * @param    string $keyword    当前查询的关键字
    * @return   object
    */
	public function setKeyword($string)
	{	
		$this->_keyword = $string;
		return $this;
	}
	
	/**
    * 取得当前要查询的关键字
    * @return   string
    */
	public function getKeyword()
	{
		return $this->_keyword;
	}
	
	/**
    * 设置返回数据条数
    * @param    int $limit    数据条数
    * @return   object
    */
	public function setLimit($limit)
	{
		$this->_limit = $limit;
		return $this;
	}
	
	/**
    * 取得返回数据条数
    * @return   int
    */
	public function getLimit()
	{
		return $this->_limit;
	}
	
	/**
    * 设定当前返回页数据
    * @param    int $page    页码数
    * @return   object
    */
	public function setPage($page)
	{
		$this->_page = $page;
		return $this;
	}
	
	/**
    * 取得当前页数
    * @return   int
    */
	public function getPage()
	{
		return $this->_page;
	}
	
	/**
    * 查询索引 对外
    * @return   array
    */
	public function query($keyword=null,$page=null,$limit=null){
		if($page != null) $this->setPage($page);
		if($limit != null) $this->setLimit($limit);
		$this->setKeyword($keyword);
    	$xml = '<query name="'.$this->_name.'" page="'.$this->_page.'" limit="'.$this->_limit.'">';
    	$xml .= '<keyword>'.$this->xmlencode($this->_keyword).'</keyword>';
    	$xml .= '</query>';
		return $this->post($xml);
		//Zend_Debug::dump($data); 
    }
    
    /**
     * 提交数据 POST XML
     * @param String $xml;
     * @return Object response;
     */
    private function post($xml){
    	$this->_xml = $xml;
    	$client = new Zend_Http_Client($this->_url);
		$client->setMethod(Zend_Http_Client::POST);
		$client->setRawData($xml);
		$response = $client->request();
		try{
			$d = Zend_Json::decode(Zend_Json::fromXml($response->getBody()));
			$data = $d['body'];
		}catch (Exception $e){
			$data['error'] = $e->getMessage();
			echo $response->getBody();
		}
		return $data;
		//echo $response->getBody();
    }
    
    /**
     * 过滤XML的代码 
     *
     * @param string $val
     * @return string
     */
	private function xmlencode($val){
		$val = str_replace("&","&amp;",$val);
		$val = str_replace("<","&lt;",$val);
		$val = str_replace(">","&gt;",$val);
		$val = str_replace("'","&apos;",$val);
		$val = str_replace("\"",'&quot;',$val);
		return $val;
	}
    
    /**
    * 加入索引数据 单条
    * @param    array $data    字段数组
    * @return   boolean
    */
	public function add(Array $data)
    {
    	$xml ='<create name="'.$this->_name.'">';
    	$xml.='<doc>';
    	foreach ($data as $field=>$val){
    		$xml.='<'.$field.'>'.$this->xmlencode($val).'</'.$field.'>';
    	}
    	$xml.='</doc>';
    	$xml .= '</create>';
    	return $this->post($xml);
    }
    /**
    * 加入索引数据 多条
    * @param    array $data    字段数组
    * @return   boolean
    */
    public function adds($datas){
    	$xml ='<create name="'.$this->_name.'">';
    	foreach($datas as $data){
    		$xml.='<doc>';
    		foreach ($data as $field=>$val){
    			$xml.='<'.$field.'>'.$this->xmlencode($val).'</'.$field.'>';
    		}
    		$xml.='</doc>';
    	}
    	$xml .= '</create>';
    	return $this->post($xml);
    }
    /**
    * 优化当前索引
    * @return   array
    */
    public function optimize()
    {
    	$xml ='<optimize name="'.$this->_name.'" />';
    	return $this->post($xml);
    }
    
    /**
    * 索引commit
    * @return   array
    */
    public function commit()
    {	
    	$xml ='<commit name="'.$this->_name.'" />';
    	return $this->post($xml);
    }
    
    /**
    * 删除索引数据
    * @param int or array $id    当前索引ID 
    * @return   int
    */
    public function delete($id)
    {
    	$xml ='<delete name="'.$this->_name.'">';
    	if(is_array($id)){
    		foreach ($id as $val){
    			$xml .='<doc id="'.$val.'"/>';
    		}
    	}else{
    		$xml .='<doc id="'.$id.'"/>';
    	}
    	$xml .= '</delete>';
    	return $this->post($xml);
    }
    
    /**
    * 更新索引数据
    * @param    int $id    当前索引ID
    * @param    int $data    当前数据数组
    * @return   int
    */
    public function update($data)
    {
    	$xml ='<update name="'.$this->_name.'">';
    	$xml .='<doc id="'.$data['id'].'">';
    	unset($data['id']);
    	foreach($data as $field=>$val){
    		$xml.='<'.$field.'>'.$this->xmlencode($val).'</'.$field.'>';
    	}
    	$xml .='</doc>';
    	$xml .= '</update>';
    	return $this->post($xml);
    }
    
    public function updates($datas){
    	$xml ='<update name="'.$this->_name.'">';
    	foreach ($datas as $data){
    		$xml .='<doc id="'.$data['id'].'">';
    		unset($data['id']);
    		foreach($data as $field=>$val){
    			$xml.='<'.$field.'>'.$this->xmlencode($val).'</'.$field.'>';
    		}
    		$xml .='</doc>';
    	}
    	$xml .= '</update>';
    	//echo $xml;
    	return $this->post($xml);
    }
    
    /**
     * 统计索引数据
     */
    public function count()
    {
    	$xml ='<count name="'.$this->_name.'" />';
    	return $this->post($xml);
    }
    
    public function getXML(){
    	return $this->_xml;
    }
}